﻿using System;
using System.IO;
using NUnit.Framework;
using Rhino.Mocks;
using ThoughtWorks.CruiseControl.Core;
using ThoughtWorks.CruiseControl.Core.Tasks.Conditions;
using ThoughtWorks.CruiseControl.Core.Util;

namespace ThoughtWorks.CruiseControl.UnitTests.Core.Tasks.Conditions
{
    [TestFixture]
    public class FileExistsTaskConditionTest
    {
        MockRepository mocks = new MockRepository();
        IFileSystem fileSystem;
        ILogger logger;

        [TestFixtureSetUp]
        public void testFixtureSetUp()
        {
            fileSystem = mocks.StrictMock<IFileSystem>();
            Expect.Call(fileSystem.FileExists("c:\\testfile1.txt")).IgnoreArguments().Do(new FileExistsDelegate(Formal)).Repeat.Any();
            logger = mocks.StrictMock<ILogger>();
            Expect.Call(delegate { logger.Debug(null, null); }).IgnoreArguments().Repeat.Any();

            mocks.ReplayAll();
        }

        [TestFixtureTearDown]
        public void TearDown()
        {
            mocks.VerifyAll();
        }

        delegate bool FileExistsDelegate(string filepath);
        private bool Formal(string filepath)
        {
            var info = new FileInfo(filepath);
            return info.FullName.Equals("c:\\testfile1.txt",StringComparison.InvariantCultureIgnoreCase);
        }

        [Test]
        [ExpectedException(typeof(System.NullReferenceException))]
        public void nullFileNameThrowsException()
        {
            FileExistsTaskCondition condition = new FileExistsTaskCondition();
            condition.FileName = null;
            condition.Eval(null);
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void InvalidPathThrowsException()
        {
            executeTest("c:\\InvalidFilename.txt<>",false);
        }

        [Test]
        [ExpectedException(typeof(NotSupportedException))]
        public void InvalidPath2ThrowsException()
        {
            executeTest("c:\\InvalidFilename.txt:test", false);
        }

        [Test]
        public void bulkTest()
        {
            executeTest("c:\\tester\\..\\TestFile1.txt", true);
            executeTest("c:\\TestFile1.txt", true);
            executeTest("c:\\testfile1.txt", true);
            executeTest("c:\\TestFile2.txt", false);
            executeTest("c:\\tester\\TestFile2.txt", false);
            executeTest("c:\\tester\\..\\TestFile2.txt", false);
            executeTest("c:\\tester\\..\\TestFile1.htm", false);
        }

        private void executeTest(string file, bool expected)
        {
            FileExistsTaskCondition condition = new FileExistsTaskCondition();
            condition.Logger = logger;
            condition.FileName = file;
            condition.FileSystem = fileSystem;

            string message = string.Format("Examined existence of file '{0}' and expected '{1}'", file, expected);
            IIntegrationResult result = IntegrationResultMother.CreateSuccessful();
            Assert.That(condition.Eval(result), Is.EqualTo(expected),message);
        }
    }
}
